home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-09 | 10.9 KB | 353 lines | [TEXT/KAHL] |
- // match.c matching functions for the wildcard AppleScript extension
- //
- // 93/11/19 File created
- // 94/01/24 *** released Wild 1.0.0 ***
- // 94/05/09 Totally removed the licensing mechanism and added the GNU comments
- //
- //--------------------------------------------------------------------------------------------------
- // Copyright © 1993, 1994 by Rainbow Hill Pty Ltd.
- //
- // This program is free software; you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation; either version 2
- // of the License, or any later version.
- //
- // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // See the GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along with this program;
- // if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- //
-
- #include <Errors.h>
- #include <string.h>
- #include "wild.h"
- #include "match.h"
-
- static Boolean matchStr(
- char *, // --> trailing part of filename to be checked
- char *, // --> fixed string to be found
- match_wild_t *, // --> list of wildcards
- short, // --> number of wildcards
- short // --> current wildcard (i.e. the wildcard to be checked here)
- );
-
- //************************************************************************************ match_criteria
- Boolean match_criteria(
- CInfoPBRec *param, // --> Cat Info Param block of the item
- wild_parm_t *parms // --> flags and wildcarded strings
- ) {
- Boolean result;
-
- result = false;
-
- // find out whether it is a file or a folder
- if ((param->dirInfo.ioFlAttrib & ioDirMask) == 0) {
-
- // it is a file
- if (parms->files == false) goto RET_LBL; // --->
-
- // check the creator if necessary
- if (
- parms->doCreator == true
- &&
- match_OSType(
- param->hFileInfo.ioFlFndrInfo.fdCreator,
- parms->creator,
- parms->doShort,
- parms->shortW
- ) == false
- ) goto RET_LBL; // --->
-
- // check the file type if necessary
- if (
- parms->doType == true
- &&
- match_OSType(
- param->hFileInfo.ioFlFndrInfo.fdType,
- parms->type,
- parms->doShort,
- parms->shortW
- ) == false
- ) goto RET_LBL; // --->
- }
- else {
-
- // it is a folder
- if (parms->folders == false) goto RET_LBL; // --->
- }
-
- // if we arrive here, the item has passed all the checks
- result = true;
-
- RET_LBL:
-
- return (result);
- } // match_criteria
-
- //************************************************************************************ match_OSType
- Boolean match_OSType(
- OSType what, // --> OSType to be matched
- OSType this, // --> with this
- Boolean doWild, // --> do wildcarding
- char wildcard // --> wildcard character
- ) {
- Boolean result;
- short k;
- char *whatP;
- char *thisP;
-
- if (doWild == false) {
- result = (what == this) ? true : false;
- }
- else {
- whatP = (char *)&what;
- thisP = (char *)&this;
- result = true;
- for (k = 0; k < 4 && result == true; k++) {
- if (whatP[k] != thisP[k] && thisP[k] != wildcard) result = false;
- }
- }
-
- return (result);
- } // match_OSType
-
- //************************************************************************************ match_setWild
- short match_setWild(
- char *what, // <-> wildcarded filename
- wild_parm_t *parms, // --> flags and wildcarded strings
- match_wild_t *wilds // <-- list of wildcards
- ) {
- short n;
- short k;
- short nWild; // returned value
- char wildChars[3];
- Boolean isWild;
-
- isWild = false;
- nWild = 0;
-
- // if the filtering is not case sensitive, convert the name to upper case
- if (parms->caseS == false) {
- c2pstr(what);
- UprString((unsigned char *)what, true);
- p2cstr(what);
- }
-
- // determine whether wildcarding is enabled and there are wildcards
- k = 0;
- if (parms->doLong == true && strchr(what, (int)parms->longW) != NULL) {
- wildChars[k++] = parms->longW;
- isWild = true;
- }
- if (parms->doShort == true && strchr(what, (int)parms->shortW) != NULL) {
- wildChars[k++] = parms->shortW;
- isWild = true;
- }
-
- // if wildcarding is enabled and there are wildcards in the name, scan the name
- // and fill in the wildcarding structure
- if (isWild) {
-
- // first of all terminate the string which contains all wildcard characters
- wildChars[k] = '\0';
-
- //
- // In the following loop, the variable 'n' is used to index the next
- // character of the string which needs to be checked. Therefore, when
- // 'n' coincides with the length of the string, the whole string has
- // been checked.
- // 'k' is used to temporarily store the distance between the current
- // position and the position of the next wildcard.
- //
- n = 0;
- do {
- k = strcspn(&what[n], (const char *)wildChars);
- if (parms->doShort == true && what[n + k] == parms->shortW) {
- if (k == 0 && nWild > 0) { // just following another wildcard ?
- wilds[nWild - 1].size++;
- wilds[nWild - 1].min++;
- wilds[nWild - 1].max++;
- }
- else {
- wilds[nWild].offset = k;
- wilds[nWild].size = 1;
- wilds[nWild].min = 1;
- wilds[nWild].max = 1;
- nWild++;
- }
- }
- else if (parms->doLong == true && what[n + k] == parms->longW) {
- if (k == 0 && nWild > 0) { // just following another wildcard ?
- wilds[nWild - 1].size++;
- wilds[nWild - 1].max = WILD_maxFilenameLen;
- }
- else {
- wilds[nWild].offset = k;
- wilds[nWild].size = 1;
- wilds[nWild].min = 0;
- wilds[nWild].max = WILD_maxFilenameLen;
- nWild++;
- }
- }
- n += k + 1;
- } while (n < strlen((const char *)what));
- } // we had to process wildcards
-
- return (nWild);
- } // match_setWild
-
- //************************************************************************************ match_string
- Boolean match_string(
- char *name, // --> string to be matched
- char *f, // --> wildcarded filename
- match_wild_t *wilds, // --> list of wildcards
- short nWild, // --> number of wildcards
- Boolean caseSens // --> true: case sensitive
- ) {
- Boolean success;
- short firstOffset;
- char ff[WILD_maxFilenameLen + 1]; // copy of the wildcarded filename
- short k;
- char *aPtr;
- char *x;
- char upName[WILD_nameLength];
-
-
- // if the filtering is not case sensitive, convert the name to upper case
- if (caseSens == false) {
- strcpy(upName, (const char *)name);
- c2pstr(upName);
- UprString((unsigned char *)upName, true);
- p2cstr(upName);
- x = upName;
- }
- else {
- x = name;
- }
-
- // handle the case when there are no wildcards at all
- if (nWild == 0) {
- if (strcmp((const char *)x, (const char *)f) == 0) {
- success = true;
- }
- else {
- success = false;
- }
- goto RETURN_LBL; // --->
- }
-
- // check whether there is a string before the first wildcard and whether it matches
- firstOffset = wilds[0].offset;
- if (firstOffset > 0 && strncmp((const char *)x, (const char *)f, firstOffset) != 0) {
- success = false;
- goto RETURN_LBL; // --->
- }
-
- // Mask the first character of each wildcarded section with a null, so that searches can
- // be done easily. Note that we do not need to mask the first wildcard because we will not
- // search the filename looking for the leading string.
- strcpy(ff, (const char *)&f[firstOffset]);
- aPtr = ff;
- for (k = 1; k < nWild; k++) {
- aPtr = &aPtr[wilds[k].offset + wilds[k - 1].size];
- *aPtr = '\0';
- }
-
- // now we can start matching from the first wildcard
- success = matchStr(&x[firstOffset], &ff[wilds[0].size], wilds, nWild, 0);
-
- RETURN_LBL:
- return (success);
- } // match_string
-
- //------------------------------------------------------------------------------------ matchStr
- static Boolean matchStr(
- char *x, // --> trailing part of filename to be checked
- char *f, // --> fixed string to be found
- match_wild_t *wilds, // --> list of wildcards
- short nWild, // --> number of wildcards
- short kWild // --> current wildcard (i.e. the wildcard to be checked here)
- ) {
- Boolean success;
- char *theStr; // pointer to the fixed string found in the filename
- char *xx; // pointer to part of 'x' to be searched for 'f'
- short len; // length of the filename part matched by the current wildcard
- short nextW; // next wildcard number (if any)
- short fLen; // length of the current fixed string
- char *nextX; // what is left to the filename to be matched by further wildcards
- char *nextF; // next wildcard and fixed string
-
- success = false;
-
- if (*f == '\0') {
- //
- // There is no fixed string. As contiguous wildcard characters are grouped into
- // wildcarding sections, the absence of a fixed string means that the wildcarded
- // filename terminates with a wildcard and that we are now processing precisely the
- // last wildcarding section. This implies that we have to match the whole 'xx'. The
- // only condition which needs to be satisfied is that the length of 'xx' is within
- // the 'min' and 'max' of the current wildcarding section.
- //
- len = strlen((const char *)x);
- if (len >= wilds[kWild].min && len <= wilds[kWild].max) success = true;
- goto RETURN_LBL; // --->
- }
-
- // Well, there is a fixed string. Let's prepare to scan what is left of the filename.
- xx = x;
- nextW = kWild + 1;
- fLen = strlen((const char *)f);
-
- // When we enter this function there is always at least one wildcard.
- // Let's search the filename to find the fixed string.
- do {
- theStr = strstr((const char *)xx, (const char *)f);
- if (theStr == NULL) goto RETURN_LBL; // --->
-
- // The matching string has been found. Calculate the length of the filename part
- // which matches the current wildcard.
- len = (short)(theStr - x);
- if (len > wilds[kWild].max) goto RETURN_LBL; // --->
- if (len < wilds[kWild].min) {
-
- // Match too short. Keep trying.
- xx++;
-
- }
- else {
-
- // String found and the match has an acceptable length. Check the rest.
- nextX = theStr + fLen;
-
- // check whether there are further wildcards and prepare to search on
- if (nextW < nWild) {
-
- // there are further wildcards (wilds.size includes the null which terminates 'f')
- nextF = f + (wilds[nextW].size + fLen);
-
- // call 'matchStr' recursively
- success = matchStr(nextX, nextF, wilds, nWild, nextW);
-
- // Prepare a new attempt to match the current wildcard. This will only be
- // necessary if 'success' is false, but let's not waste time to check it.
- xx++;
-
- } // there were further wildcards past the current one
- else {
-
- // There are no further wildcards. Check that we have no trailing characters
- // left and, if there are, try a new match before giving up.
- if (*nextX == '\0')
- success = true;
- else
- xx++;
- } // we have just processed the last wildcard
- } // the match was not too short
-
- } while (success == false);
-
- RETURN_LBL:
- return (success);
- } // matchStr
-